package cn.lili.modules.store.serviceimpl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.properties.RocketmqCustomProperties;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.BeanUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.service.CategoryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.search.utils.EsIndexUtil;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.entity.dos.StoreDetail;
import cn.lili.modules.store.entity.dto.StoreAfterSaleAddressDTO;
import cn.lili.modules.store.entity.dto.StoreSettingDTO;
import cn.lili.modules.store.entity.dto.StoreSettlementDay;
import cn.lili.modules.store.entity.vos.StoreBasicInfoVO;
import cn.lili.modules.store.entity.vos.StoreDetailVO;
import cn.lili.modules.store.entity.vos.StoreManagementCategoryVO;
import cn.lili.modules.store.entity.vos.StoreOtherVO;
import cn.lili.modules.store.mapper.StoreDetailMapper;
import cn.lili.modules.store.service.StoreDetailService;
import cn.lili.modules.store.service.StoreService;
import cn.lili.modules.verification.ImageUtil;
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
import cn.lili.rocketmq.tags.GoodsTagsEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
 * 店铺详细业务层实现
 *
 * @author pikachu
 * @since 2020-03-07 16:18:56
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class StoreDetailServiceImpl extends ServiceImpl<StoreDetailMapper, StoreDetail> implements StoreDetailService {

	/**
	 * 店铺
	 */
	@Autowired
	private StoreService storeService;
	/**
	 * 分类
	 */
	@Autowired
	private CategoryService categoryService;

	@Autowired
	private GoodsService goodsService;

	@Autowired
	private RocketmqCustomProperties rocketmqCustomProperties;

	@Autowired
	private RocketMQTemplate rocketMQTemplate;

	@Override
	public StoreDetailVO getStoreDetailVO(String storeId) {
		return this.baseMapper.getStoreDetail(storeId);
	}

	@Override
	public StoreDetailVO getStoreDetailVOByMemberId(String memberId) {
		return this.baseMapper.getStoreDetailByMemberId(memberId);
	}

	@Override
	public StoreDetail getStoreDetail(String storeId) {
		LambdaQueryWrapper<StoreDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
		lambdaQueryWrapper.eq(StoreDetail::getStoreId, storeId);
		return this.getOne(lambdaQueryWrapper);
	}

	@Override
	public Boolean editStoreSetting(StoreSettingDTO storeSettingDTO) {
		AuthUser tokenUser = Objects.requireNonNull(UserContext.getCurrentUser());
		// 修改店铺
		Store store = storeService.getById(tokenUser.getStoreId());
		BeanUtil.copyProperties(storeSettingDTO, store);
		boolean result = storeService.updateById(store);
		if (result) {
			this.updateStoreGoodsInfo(store);
		}
		return result;
	}

	@Override
	public void updateStoreGoodsInfo(Store store) {

		goodsService.updateStoreDetail(store);

		Map<String, Object> updateIndexFieldsMap = EsIndexUtil.getUpdateIndexFieldsMap(
				MapUtil.builder(new HashMap<String, Object>()).put("storeId", store.getId()).build(),
				MapUtil.builder(new HashMap<String, Object>()).put("storeName", store.getStoreName())
						.put("selfOperated", store.getSelfOperated()).build());
		String destination = rocketmqCustomProperties.getGoodsTopic() + ":"
				+ GoodsTagsEnum.UPDATE_GOODS_INDEX_FIELD.name();
		// 发送mq消息
		rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(updateIndexFieldsMap),
				RocketmqSendCallbackBuilder.commonCallback());
	}

	@Override
	public Boolean editMerchantEuid(String merchantEuid) {
		AuthUser tokenUser = Objects.requireNonNull(UserContext.getCurrentUser());
		Store store = storeService.getById(tokenUser.getStoreId());
		store.setMerchantEuid(merchantEuid);
		return storeService.updateById(store);
	}

	/**
	 * 获取待结算店铺列表
	 *
	 * @param day
	 *            结算日
	 * @return 待结算店铺列表
	 */
	@Override
	public List<StoreSettlementDay> getSettlementStore(int day) {
		return this.baseMapper.getSettlementStore(day);
	}

	/**
	 * 修改店铺的结算日
	 *
	 * @param storeId
	 *            店铺ID
	 * @param dateTime
	 *            结算日
	 */
	@Override
	public void updateSettlementDay(String storeId, DateTime dateTime) {
		this.baseMapper.updateSettlementDay(storeId, dateTime);
	}

	@Override
	public StoreBasicInfoVO getStoreBasicInfoDTO(String storeId, String trapeze) {

		StoreBasicInfoVO storeBasicInfoDTO = new StoreBasicInfoVO();
		if(StringUtils.isNotEmpty(trapeze)) {
			String[] splits = trapeze.split(",");
			String lon = splits[0];
			String lat = splits[1];
			storeBasicInfoDTO = this.baseMapper.getStoreBasicInfoDTO(storeId, lon, lat);
		}else{
			storeBasicInfoDTO = this.baseMapper.getStoreBasicInfo(storeId);
		}
		if (StringUtils.isNotEmpty(storeBasicInfoDTO.getGoodsManagementCategory())) {
			String goodsManagementCategory = storeBasicInfoDTO.getGoodsManagementCategory();
			String[] split = goodsManagementCategory.split(",");
			StringBuffer sb = new StringBuffer();
			for (String s : split) {
				Category category = categoryService.getById(s);
				if (ObjectUtil.isNotEmpty(category)) {
					sb.append(category.getName()).append(",");
				}
			}
			if (sb.length() > 0) {
				String name = sb.deleteCharAt(sb.length() - 1).toString();
				storeBasicInfoDTO.setGoodsManagementCategoryName(name);
			}
		}
		if (StringUtils.isNotBlank(storeBasicInfoDTO.getStoreAddressPath())) {
			storeBasicInfoDTO.setStoreAddressDetail(storeBasicInfoDTO.getStoreAddressPath().replaceAll(",", "")
					+ storeBasicInfoDTO.getStoreAddressDetail());
		}
		return storeBasicInfoDTO;
	}

	@Override
	public StoreAfterSaleAddressDTO getStoreAfterSaleAddressDTO() {
		String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
		return this.baseMapper.getStoreAfterSaleAddressDTO(storeId);
	}

	@Override
	public StoreAfterSaleAddressDTO getStoreAfterSaleAddressDTO(String id) {
		StoreAfterSaleAddressDTO storeAfterSaleAddressDTO = this.baseMapper.getStoreAfterSaleAddressDTO(id);
		if (storeAfterSaleAddressDTO == null) {
			storeAfterSaleAddressDTO = new StoreAfterSaleAddressDTO();
		}
		return storeAfterSaleAddressDTO;
	}

	@Override
	public boolean editStoreAfterSaleAddressDTO(StoreAfterSaleAddressDTO storeAfterSaleAddressDTO) {
		String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
		LambdaUpdateWrapper<StoreDetail> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
		lambdaUpdateWrapper.set(StoreDetail::getSalesConsigneeName, storeAfterSaleAddressDTO.getSalesConsigneeName());
		lambdaUpdateWrapper.set(StoreDetail::getSalesConsigneeAddressId,
				storeAfterSaleAddressDTO.getSalesConsigneeAddressId());
		lambdaUpdateWrapper.set(StoreDetail::getSalesConsigneeAddressPath,
				storeAfterSaleAddressDTO.getSalesConsigneeAddressPath());
		lambdaUpdateWrapper.set(StoreDetail::getSalesConsigneeDetail,
				storeAfterSaleAddressDTO.getSalesConsigneeDetail());
		lambdaUpdateWrapper.set(StoreDetail::getSalesConsigneeMobile,
				storeAfterSaleAddressDTO.getSalesConsigneeMobile());
		lambdaUpdateWrapper.eq(StoreDetail::getStoreId, storeId);
		return this.update(lambdaUpdateWrapper);
	}

	@Override
	public boolean updateStockWarning(Integer stockWarning) {
		String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId();
		LambdaUpdateWrapper<StoreDetail> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
		lambdaUpdateWrapper.set(StoreDetail::getStockWarning, stockWarning);
		lambdaUpdateWrapper.eq(StoreDetail::getStoreId, storeId);
		return this.update(lambdaUpdateWrapper);
	}

	@Override
	public List<StoreManagementCategoryVO> goodsManagementCategory(String storeId) {

		// 获取顶部分类列表
		List<Category> categoryList = categoryService.firstCategory();
		// 获取店铺信息
		StoreDetail storeDetail = this
				.getOne(new LambdaQueryWrapper<StoreDetail>().eq(StoreDetail::getStoreId, storeId));
		// 获取店铺分类
		String[] storeCategoryList = storeDetail.getGoodsManagementCategory().split(",");
		List<StoreManagementCategoryVO> list = new ArrayList<>();
		for (Category category : categoryList) {
			StoreManagementCategoryVO storeManagementCategoryVO = new StoreManagementCategoryVO(category);
			for (String storeCategory : storeCategoryList) {
				if (storeCategory.equals(category.getId())) {
					storeManagementCategoryVO.setSelected(true);
				}
			}
			list.add(storeManagementCategoryVO);
		}
		return list;
	}

	@Override
	public StoreOtherVO getStoreOtherVO(String storeId) {
		StoreOtherVO storeOtherVO = this.baseMapper.getLicencePhoto(storeId);
		String licencePhoto = storeOtherVO.getLicencePhoto();
		try {
			URL url = new URL(licencePhoto);
			InputStream inputStream = url.openStream();
			// JPEGImageDecoder jpegDecoder = JPEGCodec.createJPEGDecoder(inputStream);

			// BufferedImage bufferedImage = jpegDecoder.decodeAsBufferedImage();
			BufferedImage bufferedImage = ImageIO.read(inputStream);
			log.warn("bufferedImage" + bufferedImage);
			ImageUtil.addWatermark(bufferedImage, "百焕商圈");
			// 新建流
			ByteArrayOutputStream oriImagesOs = new ByteArrayOutputStream();
			// 利用ImageIO类提供的write方法，将bi以jpg图片的数据模式写入流
			ImageIO.write(bufferedImage, "jpg", oriImagesOs);
			byte[] oriImageByte = oriImagesOs.toByteArray();
			log.warn("oriImageByte" + oriImageByte);
			storeOtherVO.setImg("data:image/png;base64," + Base64Utils.encodeToString(oriImageByte));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return storeOtherVO;
	}

}